package com.aysafety.eventmodel.service.electromagnetic.impl;

import com.aysafety.eventmodel.common.DateUtils;
import com.aysafety.eventmodel.dao.ElectromagneticDao;
import com.aysafety.eventmodel.dao.TreeDao;
import com.aysafety.eventmodel.service.electromagnetic.ElectromagneticService;
import com.safety.algorithm.eigenvalue.EigenvalueAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @program: iotDataPlatform
 * @description: 电磁辐射
 * @author: ChengQi
 * @create: 2019-02-28 09:13
 **/
@Service public class ElectromagneticServiceImpl implements ElectromagneticService {

    @Autowired TreeDao treeDao;

    @Autowired ElectromagneticDao electromagneticDao;

    // 删除ArrayList中重复元素，保持顺序
    private static List<Map<String, Object>> removeDuplicateWithOrder(List<Map<String, Object>> list) {
        Set<Map<String, Object>> set = new HashSet();
        List<Map<String, Object>> newList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put("entId", list.get(i).get("entId"));
            map.put("workingFace", list.get(i).get("workingFace"));
            map.put("deviceId", list.get(i).get("deviceId"));
            if (set.add(map)) {
                newList.add(map);
            }
        }
        return newList;
    }


    @Override public void electromagneticRadiationWarning(String currentTime) throws Throwable {
        /**
         * 1.获取矿区名称、工作面、m值、Δt值 2.从Hbase中抓取【t-m,t】时间段的声发射强度数据,并计算出平均值，带入n小时偏差值计算
         * 3.从Hbase中抓取【t-m-Δt,t-Δt】时间段的声发射强度数据,并计算出平均值 4.计算预警指标 5.放入hbase中，同时放入RabbitMQ中等待消费
         */
        // 1.获取矿区名称、工作面、m值、Δt值
        // m值
        int m = Integer.parseInt("3");
        // Δt值
        int dt = Integer.parseInt("30");
        //树
        Map<String, Object> treeMap = new HashMap<String, Object>(1);
        treeMap.put("type", "\'" + "ElectromagneticIntensity" + "\'");
        List<Map<String, Object>> tree = removeDuplicateWithOrder(treeDao.queryTreeData(treeMap));

        // 2.从Hbase中抓取【t-m,t】时间段的声发射强度数据,[2018-12-18 14:54:00,2018-12-18 14:57:59]
        // 当前时间
        String endTime = currentTime.substring(0, 17) + "59";
        // 当前时间往前m分钟
        String startTime = DateUtils.getBeforeMinuteDate(-m, currentTime).substring(0, 17) + "00";

        for (Map<String, Object> map : tree) {
            Map<String, Object> resultMap = new HashMap<String, Object>();

            String mineId = map.get("entId").toString();
            String deviceId = map.get("deviceId").toString();
            String workingFace = map.get("workingFace").toString();

            Map<String, Object> parram = new HashMap<String, Object>();
            parram.put("tableId", mineId + "." + "ElectromagneticIntensityRealTime");
            parram.put("entId", "\'" + mineId + "\'");
            parram.put("deviceId", "\'" + deviceId + "\'");
            parram.put("startTime", DateUtils.fomatDateTime(startTime).getTime());
            parram.put("endTime", DateUtils.fomatDateTime(endTime).getTime());

            //【t-m,t】时间段的声发射强度数据
            List<Map<String, Object>> rearList = electromagneticDao.queryRealTimeByElectromagneticIntensity(parram);
            double avgRear = EigenvalueAlgorithm.average(rearList, "monitoringValue");

            //从Hbase中抓取【t-m-Δt,t-Δt】时间段的声发射强度数据
            String dEndTime = DateUtils.getBeforeMinuteDate(-dt, endTime).substring(0, 17) + "59";
            // 当前时间往前m分钟
            String dStartTime = DateUtils.getBeforeMinuteDate(-dt, startTime).substring(0, 17) + "00";
            parram.put("startTime", DateUtils.fomatDateTime(dStartTime).getTime());
            parram.put("endTime", DateUtils.fomatDateTime(dEndTime).getTime());
            List<Map<String, Object>> frontList = electromagneticDao.queryRealTimeByElectromagneticIntensity(parram);
            double avgFront = EigenvalueAlgorithm.average(frontList, "monitoringValue");

            // 4.electromagneticWarningIndicator：预警指标
            double electromagneticWarningIndicator = EigenvalueAlgorithm.warnings(avgRear, avgFront, dt);

            /*****************************计算n小时偏差值****************************/
            int n = Integer.parseInt("1");
            startTime = DateUtils.getBeforehourDate(-n, endTime);
            parram.put("startTime", DateUtils.fomatDateTime(startTime).getTime());
            rearList.clear();

            rearList = electromagneticDao.queryRealTimeByElectromagneticIntensity(parram);

            double avghours = EigenvalueAlgorithm.average(rearList, "monitoringValue");
            double hoursDeviation = EigenvalueAlgorithm.dev(avgRear - avghours, avghours, 0);

            /*****************************计算偏离异常持续时间****************************/
            double a = 0.5;
            boolean flag = EigenvalueAlgorithm.devAbnormal(hoursDeviation, a, 1);
            resultMap.put("tableId", mineId + "." + "CalElectromagneticIntensity");
            resultMap.put("pk", "\'" + DateUtils.fomatDateTime(startTime).getTime() + ".:." + deviceId + "\'");
            resultMap.put("entId", "\'" + mineId + "\'");
            resultMap.put("workingFace", "\'" + workingFace + "\'");
            resultMap.put("deviceId", "\'" + deviceId + "\'");
            resultMap.put("electromagneticWarningIndicator", electromagneticWarningIndicator);
            resultMap.put("hoursDeviation", hoursDeviation);
            resultMap.put("n", n);
            resultMap.put("m", m);
            resultMap.put("dt", dt);
            resultMap.put("a", a);
            resultMap.put("flag", flag ? 1 : 0);
            resultMap.put("datetime", DateUtils.fomatDateTime(startTime).getTime());
            electromagneticDao.saveCal(resultMap);
        }

    }

    @Override public void dailyComprehensiveWarning(String currentTime) throws Throwable {

    }
}
